package com.hd.trans.utils

import android.graphics.Bitmap
import android.media.MediaScannerConnection
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import android.text.TextUtils
import com.hd.trans.ui.base.AppContextProvider
import id.zelory.compressor.Compressor
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.ObservableOnSubscribe
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.observers.DisposableObserver
import io.reactivex.schedulers.Schedulers
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream

/**
 * @Auther hjw
 * @Date 2021/9/24/14:27
 * @Description 图片工具类
 */
object ImageUtil {

    fun save2Gallery(vararg path: String): List<String> {
        val destPaths = arrayListOf<String>()

        if (path.isNotEmpty()) {
            val galleryPath = FileUtils.getAlbumDir()

            val galleryDir = File(galleryPath)

            if (!galleryDir.exists()) {
                galleryDir.mkdir()
            }
            path.forEach {
                if (!TextUtils.isEmpty(it)) {
                    val destFile = File(galleryDir, FileUtils.getFileNameByPath(it))

                    if (copy(it, destFile.absolutePath)) {
                        destPaths.add(destFile.absolutePath)
                    }
                }

            }

            if (destPaths.isNotEmpty()) {
                MediaScannerConnection.scanFile(
                    AppContextProvider.getContext(),
                    destPaths.toTypedArray(),
                    null,
                    null
                )
                ToastUtils.showNormal("已保存到相册")
            }
        }
        return destPaths
    }

    private fun copy(oldPath: String, newPath: String): Boolean {
        try {
            var bytesum = 0
            var byteread = 0
            val oldFile = File(oldPath)
            if (oldFile.exists()) { //文件存在时
                val inStream: InputStream = FileInputStream(oldPath) //读入原文件
                val fs = FileOutputStream(newPath)
                val buffer = ByteArray(1444)
                while (inStream.read(buffer).also { byteread = it } != -1) {
                    bytesum += byteread //字节数 文件大小
                    fs.write(buffer, 0, byteread)
                }
                inStream.close()
            }
            return true
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return false
    }

    /**
     * 拍照翻译：图片压缩
     */
    fun processBitmapList(mBitmapList: List<Bitmap>?, back:((ArrayList<String>)->Unit)? = null){
        if (mBitmapList.isNullOrEmpty()) {
            return
        }

        val pathPhotos = arrayListOf<String>()
        Observable.create(ObservableOnSubscribe { emit: ObservableEmitter<ArrayList<String>?> ->
            val resultList = ArrayList<String>()
            mBitmapList.forEach {
                val mBitmap = it
                val maxValue = mBitmap.width.coerceAtLeast(mBitmap.height)
                var file: File? = null
                if (mBitmap.byteCount > 1024 * 1024 || maxValue > 1920) {
                    //拍照原图
                    val path: String = PhotoBitmapUtils.saveSourcePhotoToSD(mBitmap)
                    pathPhotos.add(path)
                    try {
                        file = Compressor(AppContextProvider.getContext())
                            /*.setMaxWidth(1080)
                            .setMaxHeight(1920)
                            .setQuality(75)*/
                            .setCompressFormat(Bitmap.CompressFormat.JPEG)
                            .setDestinationDirectoryPath(PhotoFileUtil.getPhotoTargetPath())//压缩后图片存放的文件夹
                            .compressToFile(File(path))
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }finally {
                        if (file!= null) {
                            resultList.add(file.absolutePath)
                        }
                    }
                } else {
                    val path: String = PhotoBitmapUtils.savePhotoToSD(mBitmap)
                    resultList.add(path)
                }
            }
            emit.onNext(resultList)
            emit.onComplete()
        }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : DisposableObserver<ArrayList<String>?>() {
                override fun onNext(filePaths: ArrayList<String>) {
                    back?.invoke(filePaths)
                }

                override fun onError(e: Throwable) {
                    pathPhotos.forEach {
                        if (it.isNotEmpty()) {
                            //删除原图片
                            FileUtil.deleteFile(it)
                        }
                    }
                }

                override fun onComplete() {
                    pathPhotos.forEach {
                        if (it.isNotEmpty()) {
                            //删除原图片
                            FileUtil.deleteFile(it)
                        }
                    }
                }
            })
    }

    /**
     * 拍照翻译：图片压缩
     */
    fun processBitmap(mBitmap: Bitmap?, back:((String)->Unit)? = null){
        if (mBitmap == null) {
            return
        }

        var pathPhoto = ""
        Observable.create(ObservableOnSubscribe { emit: ObservableEmitter<String?> ->
            val maxValue = mBitmap.width.coerceAtLeast(mBitmap.height)
            var file: File? = null
            if (mBitmap.byteCount > 1024 * 1024 || maxValue > 1920) {
                //拍照原图
                val path: String = PhotoBitmapUtils.saveSourcePhotoToSD(mBitmap)
                pathPhoto = path
                try {
                    file = Compressor(AppContextProvider.getContext())
                        /*.setMaxWidth(1080)
                        .setMaxHeight(1920)
                        .setQuality(75)*/
                        .setCompressFormat(Bitmap.CompressFormat.JPEG)
                        .setDestinationDirectoryPath(PhotoFileUtil.getPhotoTargetPath())//压缩后图片路径
                        .compressToFile(File(path))
                } catch (e: IOException) {
                    e.printStackTrace()
                }finally {
                    emit.onNext(file?.absolutePath?:"")
                    emit.onComplete()
                }
            } else {
                val path: String = PhotoBitmapUtils.savePhotoToSD(mBitmap)
                emit.onNext(path)
                emit.onComplete()
            }
        }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : DisposableObserver<String?>() {
                override fun onNext(filePath: String) {
                    back?.invoke(filePath)
                }

                override fun onError(e: Throwable) {
                    if(!TextUtils.isEmpty(pathPhoto)){
                        //删除原图片
                        FileUtil.deleteFile(pathPhoto)
                    }
                }

                override fun onComplete() {
                    if(!TextUtils.isEmpty(pathPhoto)){
                        //删除原图片
                        FileUtil.deleteFile(pathPhoto)
                    }
                }
            })
    }

    /**
     * 同步压缩
     */
    fun processBitmapSyn(mBitmap: Bitmap?, back:((String)->Unit)? = null){
        if (mBitmap == null) {
            return
        }

        var pathPhoto = ""
        var savePath = ""

        val maxValue = mBitmap.width.coerceAtLeast(mBitmap.height)
        var file: File? = null
        if (mBitmap.byteCount > 1024 * 1024 || maxValue > 1920) {
            //拍照原图
            val path: String = PhotoBitmapUtils.saveSourcePhotoToSD(mBitmap)
            pathPhoto = path
            try {
                file = Compressor(AppContextProvider.getContext())
                    /*.setMaxWidth(1080)
                    .setMaxHeight(1920)
                    .setQuality(75)*/
                    .setCompressFormat(Bitmap.CompressFormat.JPEG)
                    .setDestinationDirectoryPath(PhotoFileUtil.getPhotoTargetPath())//压缩后图片路径
                    .compressToFile(File(path))
            } catch (e: IOException) {
                e.printStackTrace()
            }finally {
                savePath = file?.absolutePath?:""
            }
        } else {
            savePath = PhotoBitmapUtils.savePhotoToSD(mBitmap)
        }
        back?.invoke(savePath)
        if(!TextUtils.isEmpty(pathPhoto)){
            //删除原图片
            FileUtil.deleteFile(pathPhoto)
        }
    }

    /**
     * 高斯模糊
     */
    fun blurBitmap(bitmap: Bitmap, radius: Int): Bitmap? {
        //创建一个空bitmap，其大小与我们想要模糊的bitmap大小相同
        val outBitmap = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
        //实例化一个新的Renderscript
        val rs = RenderScript.create(AppContextProvider.getContext())
        //创建Allocation对象
        val allIn = Allocation.createFromBitmap(rs, bitmap)
        val allOut = Allocation.createFromBitmap(rs, outBitmap)
        //创建ScriptIntrinsicBlur对象，该对象实现了高斯模糊算法
        val blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))

        //设置模糊半径，0 <radius <= 25
        blurScript.setRadius(radius.toFloat())

        //执行Renderscript
        blurScript.setInput(allIn)
        blurScript.forEach(allOut)
        //将allOut创建的Bitmap复制到outBitmap
        allOut.copyTo(outBitmap)
        //释放内存占用
        bitmap.recycle()

        //销毁Renderscript。
        rs.destroy()
        return outBitmap
    }
}